package com.jingxuan.service.impl;

import com.jingxuan.common.exception.BusinessException;
import com.jingxuan.common.result.ResultCode;
import com.jingxuan.dto.request.UpdatePasswordRequest;
import com.jingxuan.dto.request.UserLoginRequest;
import com.jingxuan.dto.request.UserRegisterRequest;
import com.jingxuan.dto.request.UserUpdateRequest;
import com.jingxuan.dto.response.UserInfoResponse;
import com.jingxuan.entity.Permission;
import com.jingxuan.entity.Role;
import com.jingxuan.entity.User;
import com.jingxuan.mapper.PermissionMapper;
import com.jingxuan.mapper.RoleMapper;
import com.jingxuan.mapper.UserMapper;
import com.jingxuan.service.UserService;
import com.jingxuan.util.JsonUtil;
import com.jingxuan.util.MD5Util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户服务实现类
 */
@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private PermissionMapper permissionMapper;

    @Autowired
    private com.jingxuan.controller.FileController fileController;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserInfoResponse register(UserRegisterRequest request) {
        // 检查手机号是否已存在
        User existUser = userMapper.selectByPhone(request.getPhone());
        if (existUser != null) {
            throw new BusinessException(ResultCode.PHONE_EXISTS);
        }

        // 创建用户对象
        User user = new User();
        user.setUserName(request.getUserName());
        user.setPhoneNumber(request.getPhone());
        user.setBirthdate(request.getBirthdate());
        user.setAvatar(request.getIcon());
        user.setStatus(user.getStatus() == null ? 1 : user.getStatus());

        // 生成盐值和加密密码
        String encryptedPwd = MD5Util.encode(request.getPassword());
        String salt = encryptedPwd.split("@")[0];
        user.setSalt(salt);
        user.setPwd(encryptedPwd);

        // 处理用户喜好（将List转为JSON字符串存储）
        if (request.getPreferences() != null && !request.getPreferences().isEmpty()) {
            user.setPreferences(JsonUtil.listToJson(request.getPreferences()));
        }

        // 插入用户
        int result = userMapper.insert(user);
        if (result <= 0) {
            throw new BusinessException(ResultCode.DATABASE_ERROR, "用户注册失败");
        }

        // 为用户分配默认角色（ROLE_USER）
        Role userRole = roleMapper.selectByRoleName("ROLE_USER");
        if (userRole != null) {
            roleMapper.insertUserRole(user.getId(), userRole.getId());
        }

        // 构建响应
        UserInfoResponse response = new UserInfoResponse();
        response.setUserId(user.getId());
        response.setUserName(user.getUserName());
        response.setPhone(user.getPhoneNumber());
        response.setBirthdate(user.getBirthdate());
        response.setIcon(user.getAvatar());
        response.setGender(user.getGender());
        response.setStatus(user.getStatus());
        response.setRegisteredAt(user.getCreatedAt() != null ? user.getCreatedAt().toString() : "");
        response.setPreferences(JsonUtil.jsonToList(user.getPreferences()));

        log.info("用户注册成功，userId: {}", user.getId());
        return response;
    }

    @Override
    public UserInfoResponse getUserById(Long userId) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException(ResultCode.USER_NOT_FOUND);
        }

        // 查询用户角色
        List<Role> roles = roleMapper.selectByUserId(userId);
        List<String> roleNames = roles.stream()
                .map(Role::getRoleName)
                .collect(Collectors.toList());

        // 查询用户权限
        List<Permission> permissions = permissionMapper.selectByUserId(userId);
        List<String> permissionNames = permissions.stream()
                .map(Permission::getPermissionName)
                .collect(Collectors.toList());

        UserInfoResponse response = new UserInfoResponse();
        response.setUserId(user.getId());
        response.setUserName(user.getUserName());
        response.setPhone(user.getPhoneNumber());
        response.setBirthdate(user.getBirthdate());
        response.setIcon(user.getAvatar());
        response.setGender(user.getGender());
        response.setStatus(user.getStatus());
        response.setPreferences(JsonUtil.jsonToList(user.getPreferences()));
        response.setRegisteredAt(user.getCreatedAt() != null ? user.getCreatedAt().toString() : "");
        response.setRoles(roleNames);
        response.setPermissions(permissionNames);

        return response;
    }

    @Override
    public List<UserInfoResponse> getUserList(String keyword) {
        String cleanKeyword = (keyword != null && !keyword.trim().isEmpty()) ? keyword.trim() : null;
        List<User> users = userMapper.selectList(cleanKeyword);
        return users.stream().map(user -> {
            UserInfoResponse response = new UserInfoResponse();
            response.setUserId(user.getId());
            response.setUserName(user.getUserName());
            response.setPhone(user.getPhoneNumber());
            response.setBirthdate(user.getBirthdate());
            response.setIcon(user.getAvatar());
            response.setGender(user.getGender());
            response.setStatus(user.getStatus());
            response.setRegisteredAt(user.getCreatedAt() != null ? user.getCreatedAt().toString() : "");

            // 简单列表不需要加载所有角色和权限，如果需要可以额外查询
            // 这里为了性能暂不加载详细角色权限，或者只加载角色名
            List<Role> roles = roleMapper.selectByUserId(user.getId());
            List<String> roleNames = roles.stream().map(Role::getRoleName).collect(Collectors.toList());
            response.setRoles(roleNames);

            return response;
        }).collect(Collectors.toList());
    }

    /**
     * 更新用户信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserInfoResponse updateUser(Long userId, UserUpdateRequest request) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException(ResultCode.USER_NOT_FOUND);
        }

        // 更新用户信息
        if (request.getUserName() != null) {
            user.setUserName(request.getUserName());
        }
        if (request.getPhone() != null) {
            // 检查新手机号是否已被其他用户使用
            User existUser = userMapper.selectByPhone(request.getPhone());
            if (existUser != null && !existUser.getId().equals(userId)) {
                throw new BusinessException(ResultCode.PHONE_EXISTS);
            }
            user.setPhoneNumber(request.getPhone());
        }
        if (request.getPassword() != null) {
            // 重新生成盐值并加密密码
            String encryptedPwd = MD5Util.encode(request.getPassword());
            String salt = encryptedPwd.split("@")[0];
            user.setSalt(salt);
            user.setPwd(encryptedPwd);
        }
        if (request.getBirthdate() != null) {
            user.setBirthdate(request.getBirthdate());
        }
        if (request.getIcon() != null) {
            // 如果用户已有头像且新头像与旧头像不同，删除旧头像文件
            String oldAvatar = user.getAvatar();
            if (oldAvatar != null && !oldAvatar.isEmpty() && !oldAvatar.equals(request.getIcon())) {
                log.info("删除旧头像文件: {}", oldAvatar);
                fileController.deleteFile(oldAvatar);
            }
            user.setAvatar(request.getIcon());
        }
        if (request.getPreferences() != null) {
            // 将List转为JSON字符串存储
            user.setPreferences(JsonUtil.listToJson(request.getPreferences()));
        }
        if (request.getGender() != null) {
            user.setGender(request.getGender());
        }
        if (request.getStatus() != null) {
            user.setStatus(request.getStatus());
        }
        // if (request.getInfo() != null) {
        // user.setInfo(request.getInfo());
        // }

        // 更新角色（仅管理员操作时有效，Controller层已做权限校验，这里直接处理）
        if (request.getRole() != null) {
            roleMapper.deleteUserRoles(userId);
            String roleName = request.getRole();
            // 兼容前端传来的中文角色名或英文角色名
            if ("管理员".equals(roleName) || "超级管理员".equals(roleName)) {
                roleName = "ROLE_ADMIN";
            } else if ("普通用户".equals(roleName) || "正常".equals(roleName)) {
                roleName = "ROLE_USER";
            }
            
            Role role = roleMapper.selectByRoleName(roleName);
            if (role != null) {
                roleMapper.insertUserRole(userId, role.getId());
            }
        }

        int result = userMapper.update(user);
        if (result <= 0) {
            throw new BusinessException(ResultCode.DATABASE_ERROR, "更新用户信息失败");
        }

        log.info("用户信息更新成功，userId: {}", userId);
        return getUserById(userId);
    }

    /**
     * 删除用户
     */
    @Override
    public void deleteUser(Long userId) {
        int result = userMapper.deleteById(userId);
        if (result <= 0) {
            throw new BusinessException(ResultCode.DATABASE_ERROR, "删除用户失败");
        }
        log.info("用户删除成功，userId: {}", userId);
    }

    /**
     * 根据手机号获取用户
     */
    @Override
    public User getUserByPhone(String phone) {
        return userMapper.selectByPhone(phone);
    }

    @Override
    public UserInfoResponse login(UserLoginRequest request) {
        // 查询手机号是否存在
        User user = userMapper.selectByPhone(request.getPhone());
        if (user == null) {
            throw new BusinessException(ResultCode.USER_NOT_FOUND);
        }

        // 验证密码
        boolean isPasswordValid = MD5Util.verify(user.getPwd(), request.getPassword());
        if (!isPasswordValid) {
            throw new BusinessException(ResultCode.LOGIN_FAILED);
        }

        // 获取用户信息（包含角色和权限）
        UserInfoResponse response = getUserById(user.getId());

        log.info("用户登录成功，userId: {}, roles: {}, permissions: {}",
                user.getId(), response.getRoles(), response.getPermissions());

        return response;
    }

    @Override
    public UserInfoResponse updateUserPreferences(Long userId, UserUpdateRequest request) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException(ResultCode.USER_NOT_FOUND);
        }
        user.setPreferences(JsonUtil.listToJson(request.getPreferences()));
        userMapper.update(user);
        return getUserById(userId);
    }

    /**
     * 修改密码
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserInfoResponse updatePassword(Long userId, UpdatePasswordRequest request) {
        // 查询用户
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException(ResultCode.USER_NOT_FOUND);
        }

        // 验证旧密码
        boolean isOldPasswordValid = MD5Util.verify(user.getPwd(), request.getOldPassword());
        if (!isOldPasswordValid) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "旧密码不正确");
        }

        // 检查新密码不能与旧密码相同
        boolean isSamePassword = MD5Util.verify(user.getPwd(), request.getNewPassword());
        if (isSamePassword) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "新密码不能与旧密码相同");
        }

        // 加密新密码
        String encryptedPwd = MD5Util.encode(request.getNewPassword());
        String salt = encryptedPwd.split("@")[0];
        user.setSalt(salt);
        user.setPwd(encryptedPwd);

        // 更新数据库
        int result = userMapper.update(user);
        if (result <= 0) {
            throw new BusinessException(ResultCode.DATABASE_ERROR, "修改密码失败");
        }

        log.info("用户密码修改成功，userId: {}", userId);
        return getUserById(userId);
    }

    @Override
    public List<UserInfoResponse> getAdminList(String keyword) {
        String cleanKeyword = (keyword != null && !keyword.trim().isEmpty()) ? keyword.trim() : null;
        List<User> users = userMapper.selectListByRole("ROLE_ADMIN", cleanKeyword);
        return users.stream().map(user -> {
            UserInfoResponse response = new UserInfoResponse();
            response.setUserId(user.getId());
            response.setUserName(user.getUserName());
            response.setPhone(user.getPhoneNumber());
            response.setBirthdate(user.getBirthdate());
            response.setIcon(user.getAvatar());
            response.setGender(user.getGender());
            response.setStatus(user.getStatus());
            response.setRegisteredAt(user.getCreatedAt() != null ? user.getCreatedAt().toString() : "");
            
            List<Role> roles = roleMapper.selectByUserId(user.getId());
            List<String> roleNames = roles.stream().map(Role::getRoleName).collect(Collectors.toList());
            response.setRoles(roleNames);

            return response;
        }).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserInfoResponse createAdmin(UserRegisterRequest request) {
        // 检查手机号是否已存在
        User existUser = userMapper.selectByPhone(request.getPhone());
        if (existUser != null) {
            throw new BusinessException(ResultCode.PHONE_EXISTS);
        }

        // 创建用户对象
        User user = new User();
        user.setUserName(request.getUserName());
        user.setPhoneNumber(request.getPhone());
        user.setBirthdate(request.getBirthdate());
        user.setAvatar(request.getIcon());
        user.setStatus(1); // 默认启用
        user.setGender(request.getGender() != null ? request.getGender() : "男");

        // 生成盐值和加密密码
        String encryptedPwd = MD5Util.encode(request.getPassword());
        String salt = encryptedPwd.split("@")[0];
        user.setSalt(salt);
        user.setPwd(encryptedPwd);

        // 插入用户
        int result = userMapper.insert(user);
        if (result <= 0) {
            throw new BusinessException(ResultCode.DATABASE_ERROR, "管理员创建失败");
        }

        // 为用户分配管理员角色（ROLE_ADMIN）
        Role adminRole = roleMapper.selectByRoleName("ROLE_ADMIN");
        if (adminRole != null) {
            roleMapper.insertUserRole(user.getId(), adminRole.getId());
        }

        // 构建响应
        return getUserById(user.getId());
    }

}
